<template>
  <div>
    <el-form
      style="margin-top: 18px"
      size="mini"
      v-loading="filterDataLoading"
      element-loading-text="拼命加载中"
      element-loading-spinner="el-icon-loading"
      element-loading-background="rgba(0, 0, 0, 0.8)"
    >
      <el-form-item>
        <div v-for="(obj, idx) in filterData" :key="idx" class="condition-row">
          <el-tag size="mini">{{obj.dimName}}</el-tag>
          <el-select v-model="obj.type" @change="buildFilterGroupData">
            <el-option
              v-for="(type, idx) in obj.filterTypeOptions"
              :label="type.label"
              :value="type.value"
              :key="idx"
            ></el-option>
          </el-select>
          <!--       如果是自定义标签，只有【是】选项           -->
          <el-radio-group v-model="obj.valueList[0]" v-if="isTagCustom(obj)">
            <el-radio label="0">是</el-radio>
          </el-radio-group>
          <!--       如果是分类标签，只匹配一个字典项           -->
          <el-select
            v-else-if="isFilterSingle(obj)"
            v-model="obj.valueList[0]"
            filterable
            clearable
            @change="buildFilterGroupData"
          >
            <el-option
              v-for="(item, idx) in obj.valueOptions"
              :label="item.itemName"
              :value="item.itemNo"
              :key="idx"
            ></el-option>
          </el-select>
          <!--        如果是数值标签，并且筛选条件匹配的是一个数字        -->
          <el-input
            v-else-if="isNumberSingle(obj)"
            v-model="obj.valueList[0]"
            clearable
            @change="buildFilterGroupData"
            style="width: 300px"
          ></el-input>
          <!--        如果是数值标签，并且筛选条件匹配的是我两个数字        -->
          <div v-else-if="isNumberDouble(obj)" class="flex-row">
            <el-input v-model="obj.valueList[0]" clearable @change="buildFilterGroupData"></el-input>
            -
            <el-input v-model="obj.valueList[1]" clearable @change="buildFilterGroupData"></el-input>
          </div>
          <el-select
            v-else
            v-model="obj.valueList"
            filterable
            multiple
            clearable
            :allow-create="!obj.valueOptions.length"
            :default-first-option="!obj.valueOptions.length"
            style="flex:1"
            @change="buildFilterGroupData"
          >
            <el-option
              v-for="(item, idx) in obj.valueOptions"
              :label="item.itemName"
              :value="item.itemNo"
              :key="idx"
            ></el-option>
          </el-select>
          <div style="width: 130px">
            <el-button type="text" icon="el-icon-close" @click="onRemoveFilterData(idx)"></el-button>
            <el-tooltip
              :manual="true"
              content="请组合筛选条件"
              placement="top"
              v-if="idx===0"
              v-model="filterGroupPopover">
              <el-button
                type="text"
                icon="el-icon-setting"
                @click="showFilterGroupTree"
              >条件设置
              </el-button>
            </el-tooltip>
          </div>
        </div>
      </el-form-item>
    </el-form>

    <el-dialog
      title="组合筛选条件"
      :visible.sync="filterGroupDialog"
      class="confirm-dialog"
      :show-close="false"
      :close-on-click-modal="false"
    >
      <div class="flex-row flex-justify-between flex-align-center">
        <div>
          <filters-group :filter-group.sync="filterGroupData" :draggable="true"></filters-group>
        </div>
        <div style="padding: 0 50px 20px 50px; border-left: 1px solid #d3d3d3">
          <div>示例：</div>
          <img
            src="@/assets/images/group-filter-demo.png"
            alt="筛选示例图"
            style="width: 250px; height: 150px;margin-top: 20px"
          >
        </div>
      </div>

      <div class="confirm-dialog__btns">
        <el-button size="mini" type="primary" @click="onConfirmFilterGroup">确定</el-button>
        <el-button size="mini" @click="onRejectFilterGroup">取消</el-button>
        
      </div>
    </el-dialog>
  </div>
</template>

<script>
  export default {
    name: 'FilterList',
    props: {
      dataSource: {
        type: Array,
        default: function () {
          return []
        }
      },
      maxLength: {
        type: Number,
        default: 10
      },
      defaultFilterGroup: {
        type: Object,
        default: function () {
          return {}
        }
      },
      defaultFilterList: {
        type: Array,
        default: function () {
          return []
        }
      }
    },
    data () {
      return {
        tags: this.dataSource,
        filterData: [],
        filterDataLoading: false,
        filterGroupPopover: false,
        filterGroupDialog: false,
        filterGroupData: {},
        filterGroupDataOrigin: {},
        filterGroupDataEmpty: true
      }
    },
    watch: {
      'dataSource': function (val) {
        this.tags = val
      },
      'defaultFilterList': async function (val) {
        this.filterDataLoading = true
        const filterData = Utils.Object.clone(this.defaultFilterList)
        for (let obj of filterData) {
          let valueOptions = await this.$get('/api/dimItem/list', {dimId: obj.dimId})
          obj.valueOptions = valueOptions || []
          obj.filterTypeOptions = this.buildFilterTypeOptions(obj.classify, valueOptions.length > 0)
        }
        this.filterData = filterData
        this.filterDataLoading = false
      },
      'defaultFilterGroup': function () {
        this.filterGroupData = this.defaultFilterGroup
        this.filterGroupDataEmpty = false
      }
    },
    methods: {
      /**
       * ref方法
       */
      async pushData (tag) {
        if (this.filterData.length >= 10) {
          return this.$message.warning('拖拽的标签过多')
        }
        if (this.filterData.map(item => item.dimId).includes(tag.dimId)) {
          return this.$message.warning('已存在该筛选项')
        }
        this.filterDataLoading = true
        let classify = tag.classify
        let dimLargeType = tag.dimLargeType
        let valueOptions = []
        // [数值标签] 和 [自定义标签] 不需要请求标签项
        if (!Mapping.tools.valueEqMapping(Mapping.tag.classify.index.value, classify) && !Mapping.tools.valueEqMapping(Mapping.tag.dimLargeType.custom.value, dimLargeType)) {
          valueOptions = await this.$get('/api/dimItem/list', {dimId: tag.dimId})
        }
        this.filterData.push({
          dimId: tag.dimId,
          dimName: tag.dimName,
          id: '',
          type: '',
          valueList: this.isTagCustom(tag) ? ['0'] : [],
          valueOptions,
          classify,
          dimLargeType,
          filterTypeOptions: this.buildFilterTypeOptions(classify, valueOptions.length > 0, dimLargeType)
        })
        this.filterDataLoading = false
        this.buildFilterGroupData()
      },
      /**
       * ref 方法，获取组合好的标签
       */
      getFilterGroup () {
        if (this.filterGroupDataEmpty) {
          return false
        }
        return this.filterGroupData
      },
      // 筛选项是否是单匹配
      isFilterSingle (tag) {
        return Mapping.tools.valueEqMapping(Mapping.tag.classify.category.value, tag.classify)
      },
      // 只匹配一个数字的情况: 是数值型标签，并且筛选项不是【在……之中】
      isNumberSingle (tag) {
        return Mapping.tools.valueEqMapping(Mapping.tag.classify.index.value, tag.classify) && !Mapping.tools.valueEqMapping(Mapping.group.filterType.among.value, tag.type)
      },
      // 匹配两个数字的情况：是数值型标签，并且筛选项是【在……之中】
      isNumberDouble (tag) {
        return Mapping.tools.valueEqMapping(Mapping.tag.classify.index.value, tag.classify) && Mapping.tools.valueEqMapping(Mapping.group.filterType.among.value, tag.type)
      },
      /**
       * 移除筛选项
       * @param idx
       */
      onRemoveFilterData (idx) {
        this.filterData.splice(idx, 1)
        this.buildFilterGroupData()
      },
      // 每次筛选项变动都要重新 构建匹配规则
      buildFilterGroupData () {
        this.filterGroupDataEmpty = true
        let temp = {symbol: 'and', filters: [], children: [], location: '0'}
        this.filterData.map((f, i) => {
          let tempFilters = {}
          tempFilters.dimName = f.dimName
          tempFilters.dimId = f.dimId
          tempFilters.valueList = f.valueList ? f.valueList : []
          tempFilters.type = f.type
          tempFilters.id = f.id
          tempFilters.classify = f.classify

          temp.filters.push(tempFilters)
        })
        this.filterGroupData = temp
        this.filterGroupPopover = true
      },
      showFilterGroupTree () {
        if (!this.checkFilterList()) {
          return false
        }
        this.filterGroupDataOrigin = this.filterGroupData
        this.filterGroupDialog = true
        this.filterGroupPopover = false
      },
      // 根据标签类型 设置可选标签下拉值
      // tagClassify 标签类型
      // hasDic 是否有字典项
      // dimLargeType 标签大类
      buildFilterTypeOptions (tagClassify, hasDic, dimLargeType) {
        // [分类标签] 只有 [等于,不等于] 操作
        if (Mapping.tools.valueEqMapping(Mapping.tag.dimLargeType.custom.value, dimLargeType)) {
          return [Mapping.group.filterType.equal, Mapping.group.filterType.noEqual]
        }
        // [分类标签] 只有 等于操作
        if (Mapping.tools.valueEqMapping(Mapping.tag.classify.category.value, tagClassify) || Mapping.tools.valueEqMapping(Mapping.tag.dimLargeType.custom.value, dimLargeType)) {
          return [Mapping.group.filterType.equal]
        }
        let options = []
        if (Mapping.tools.valueEqMapping(Mapping.tag.classify.index.value, tagClassify)) {
          options = Mapping.tools.transferOptions(Mapping.group.filterType)
        } else {
          if (hasDic) {
            options.push(Mapping.group.filterType.equal)
            options.push(Mapping.group.filterType.noEqual)
          }
          options.push(Mapping.group.filterType.term)
          options.push(Mapping.group.filterType.noTerm)
        }
        return options
      },
      onConfirmFilterGroup () {
        this.filterGroupDialog = false
        this.filterGroupDataOrigin = {}
        this.filterGroupDataEmpty = false
      },
      onRejectFilterGroup () {
        this.filterGroupData = this.filterGroupDataOrigin
        this.filterGroupDialog = false
      },
      isTagCustom (tag) {
        return Mapping.tools.valueEqMapping(Mapping.tag.dimLargeType.custom.value, tag.dimLargeType)
      },
      checkFilterList () {
        const filterList = Utils.Object.clone(this.filterData)
        for (let obj of filterList) {
          const emptyType = !obj.type
          const emptyValue = obj.valueList.filter(item => item).length === 0
          if (emptyType || emptyValue) {
            this.$message.warning(`请将标签项【${obj.dimName}】的筛选项配置完整！`)
            return false
          }
          // 如果是数值型标签，那输入的一定是数字
          if (Mapping.tools.valueEqMapping(Mapping.tag.classify.index, obj.classify)) {
            // 如果筛选类型是[在...之中]的话，筛选项只能是两个数字范围
            if (Mapping.tools.valueEqMapping(Mapping.group.filterType.among.value, obj.type)) {
              let ok = obj.valueList.length === 2
              if (ok) {
                ok = !isNaN(obj.valueList[0]) && !isNaN(obj.valueList[1])
              }
              if (ok) {
                ok = obj.valueList[0] < obj.valueList[1]
              }
              if (!ok) {
                this.$message.warning(`标签项【${obj.dimName}】的筛选项只能输入两个数字！并且第一个数字不可大于第二个数字`)
                return false
              }
            } else {
              if (isNaN(obj.valueList[0])) {
                this.$message.warning(`标签项【${obj.dimName}】的筛选项只能输入数字`)
                return false
              }
            }
          }
        }
        return true
      }
    }
  }
</script>

<style scoped lang="less">
  @import '../assets/style/base/themeColor';

  .filter-conditions {
    margin-top: 20px;

    .condition-row {
      display: flex;
      align-items: center;
      margin: 0 0 10px 0;

      & > div, & > span {
        margin: 0 10px 0 0;
      }
    }
  }

  .confirm-dialog {
    /deep/ .el-dialog {
      border-radius: 5px;

      .el-dialog__header {
        background: @themeColor;

        .el-dialog__title {
          color: #fff;
          font-size: 12px;
        }
      }

      .confirm-dialog__info {
        padding: 5px 0;
        display: flex;

        .label {
          font-size: 12px;
          font-weight: bold;
        }

        .text {
          font-size: 12px;
          font-weight: bold;
          color: #666;
          margin-left: 5px;
        }
      }

      .confirm-dialog__btns {
        text-align: center;
        margin: 35px 0 0 0;
      }
    }
  }

  /deep/ .el-popover {
    min-width: auto;
    padding: 7px 9px;
    font-size: 12px;
    background: #303133;
    color: #fff;
  }
</style>
